package com.jyw.business.obstacles.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.jyw.business.obstacles.constant.OrderCurrStateConstant;
import com.jyw.business.obstacles.constant.OrderDealTypeConstant;
import com.jyw.business.obstacles.constant.OrderProcessStateConstant;
import com.jyw.business.obstacles.domain.*;
import com.jyw.business.obstacles.domain.dto.web.*;
import com.jyw.business.obstacles.domain.dto.wechat.WxCallRecordPageDto;
import com.jyw.business.obstacles.domain.vo.web.*;
import com.jyw.business.obstacles.domain.vo.wechat.*;
import com.jyw.business.obstacles.enums.TempEnum;
import com.jyw.business.obstacles.mapper.ObsOrderInfoMapper;
import com.jyw.business.obstacles.service.*;
import com.jyw.common.constant.ConfigKeyConstant;
import com.jyw.common.constant.SysDictTypeConstant;
import com.jyw.common.core.domain.entity.SysDictData;
import com.jyw.common.core.page.BasePage;
import com.jyw.common.exception.ServiceException;
import com.jyw.common.utils.*;
import com.jyw.system.domain.dto.BaseTimeDto;
import com.jyw.system.domain.vo.UserCacheVo;
import com.jyw.system.service.ISysConfigService;
import com.jyw.system.service.ISysDeptIpAddressService;
import com.jyw.system.utils.ConversionUtil;
import com.jyw.system.utils.UserUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 工单基本信息Service业务层处理
 *
 * @author system
 * @date 2023-08-10
 */
@Service
public class ObsOrderInfoServiceImpl extends ServiceImpl<ObsOrderInfoMapper, ObsOrderInfo> implements IObsOrderInfoService {
    @Resource
    private ObsOrderInfoMapper obsOrderInfoMapper;

    @Resource
    private IObsOrderFaultService orderFaultService;

    @Resource
    private IObsOrderMakeService makeService;

    @Resource
    private IObsOrderAssistService assistService;

    @Resource
    private IObsOrderSendService orderSendService;

    @Resource
    private IObsOrderProcessService processService;

    @Resource
    private IObsOrderEvaluateService evaluateService;

    @Resource
    private ISysConfigService configService;

    @Resource
    private ISysDeptIpAddressService sysDeptIpAddressService;

    /**
     * 工单号前缀
     */
    private final static String ORDER_NUM_PREFIX = "JYW-O";

    /**
     * 查询工单基本信息
     *
     * @param id 工单基本信息主键
     * @return 工单基本信息
     */
    @Override
    public ObsOrderInfo selectObsOrderInfoById(Long id) {
        return obsOrderInfoMapper.selectObsOrderInfoById(id);
    }

    /**
     * 查询工单基本信息列表
     *
     * @param obsOrderInfo 工单基本信息
     * @return 工单基本信息
     */
    @Override
    public List<ObsOrderInfo> selectObsOrderInfoList(ObsOrderInfo obsOrderInfo) {
        return obsOrderInfoMapper.selectObsOrderInfoList(obsOrderInfo);
    }

    /**
     * 新增工单基本信息
     *
     * @param obsOrderInfo 工单基本信息
     * @return 结果
     */
    @Override
    public int insertObsOrderInfo(ObsOrderInfo obsOrderInfo) {
        obsOrderInfo.setCreateTime(DateUtils.getNowDate());
        return obsOrderInfoMapper.insertObsOrderInfo(obsOrderInfo);
    }

    /**
     * 修改工单基本信息
     *
     * @param obsOrderInfo 工单基本信息
     * @return 结果
     */
    @Override
    public int updateObsOrderInfo(ObsOrderInfo obsOrderInfo) {
        obsOrderInfo.setUpdateTime(DateUtils.getNowDate());
        return obsOrderInfoMapper.updateObsOrderInfo(obsOrderInfo);
    }

    /**
     * 批量删除工单基本信息
     *
     * @param ids 需要删除的工单基本信息主键
     * @return 结果
     */
    @Override
    public int deleteObsOrderInfoByIds(Long[] ids) {
        return obsOrderInfoMapper.deleteObsOrderInfoByIds(ids);
    }

    /**
     * 删除工单基本信息信息
     *
     * @param id 工单基本信息主键
     * @return 结果
     */
    @Override
    public int deleteObsOrderInfoById(Long id) {
        return obsOrderInfoMapper.deleteObsOrderInfoById(id);
    }

    @Override
    public String generateOrderNum() {
        //查询最大的工单号是多少
        Long maxCode = obsOrderInfoMapper.selectMaxOrderNum();
        String today = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        if (StringUtils.isEmpty(maxCode)) {
            return String.format("%s%s%s", ORDER_NUM_PREFIX, today, CodeUtils.autoGenericCode("0", 4));
        } else {
            //取日期是否一致
            if (!today.equals(maxCode.toString().substring(0, 8))) {
                //不一致从1开始
                return String.format("%s%s%s", ORDER_NUM_PREFIX, today, CodeUtils.autoGenericCode("0", 4));
            } else {
                //如果一致取后面编号数
                String code = maxCode.toString().substring(8);
                return String.format("%s%s%s", ORDER_NUM_PREFIX, today, CodeUtils.autoGenericCode(code.toString(), (Integer.valueOf(code) + 1) <= 9999 ? 4 : code.toString().length()));
            }
        }
    }

    @Override
    public ObsOrderInfo getInfoByOrderNum(String orderNum) {
        return getOne(new QueryWrapper<ObsOrderInfo>().setEntity(new ObsOrderInfo() {{
            setOrderNum(orderNum);
        }}));
    }

    /**
     * 查询通话记录
     *
     * @param callRecordPageDto
     * @return
     */
    @Override
    public List<CallRecordPageVO> selectRecordList(CallRecordPageDto callRecordPageDto) {
        List<CallRecordPageVO> list = obsOrderInfoMapper.selectRecordList(callRecordPageDto);
        return ConversionUtil.conversionList(list, CallRecordPageVO.class);
    }

    @Override
    public List<WxCallRecordPageVO> selectWxRecordList(WxCallRecordPageDto wxCallRecordPageDto) {
        return obsOrderInfoMapper.selectWxRecordList(wxCallRecordPageDto);
    }

    @Override
    public WxWorkOrderQueryInfoVO getDetailByOrderNum(String orderNum) {
        WxWorkOrderQueryInfoVO wxWorkOrderQueryInfoVO = new WxWorkOrderQueryInfoVO();
        WxWorkOrderInfoVO info = obsOrderInfoMapper.findByOrderNum(orderNum);
        // 转换IP地址
        String ipAddress=sysDeptIpAddressService.joinIpAddress(info.getIpAddressId());
        info.setIpAddress(ipAddress);

        if (!ObjectUtils.isEmpty(info)) {
            wxWorkOrderQueryInfoVO.setInfo(info);
        }
        ObsOrderFault obsOrderFault = orderFaultService.getFaultByOrder(orderNum);
        if (!ObjectUtils.isEmpty(obsOrderFault)) {
            //查询当前处理人
            ObsOrderMake make = makeService.lambdaQuery().eq(ObsOrderMake::getOrderNum, orderNum).one();
            WxWorkOrderFaultVO vo1 = ConversionUtil.conversion(new WxWorkOrderFaultVO(obsOrderFault,make),
                    WxWorkOrderFaultVO.class);
            wxWorkOrderQueryInfoVO.setFault(vo1);
        }
        ObsOrderEvaluate evaluate = evaluateService.lambdaQuery().eq(ObsOrderEvaluate::getOrderNum, orderNum).one();
        if (!ObjectUtils.isEmpty(evaluate)) {
            WxWorkOrderEvaluateVO evaluateVo = ConversionUtil.conversion(new WxWorkOrderEvaluateVO(evaluate),
                    WxWorkOrderEvaluateVO.class);
            wxWorkOrderQueryInfoVO.setEvaluate(evaluateVo);
        }
        //接单信息
        WxWorkOrderReceiveVO orderReceiveVO = makeService.getInfoByOrderNum(orderNum);
        if (!ObjectUtils.isEmpty(orderReceiveVO)) {
            wxWorkOrderQueryInfoVO.setReceive(orderReceiveVO);
        }
        //派单信息
        List<WxWorkOrderSendVO> sendList = orderSendService.queryOrderSendList(orderNum);
        if (CollectionUtil.isNotEmpty(sendList)) {
            wxWorkOrderQueryInfoVO.setSendList(sendList);
        }
        //协作信息(子工单)
        List<AssistMainVO> assistList = assistDetail(orderNum);
        wxWorkOrderQueryInfoVO.setAssistList(assistList);
        //协作信息主工单
        AssistMainDetailVO mainDetailVO = assistMain(obsOrderFault);
        if (!ObjectUtils.isEmpty(mainDetailVO)) {
            wxWorkOrderQueryInfoVO.setAssistMain(mainDetailVO);
        }
        //处理信息
        List<MakeProcessVO> makeProcessVOS = makeDetail(orderNum,obsOrderFault);
        wxWorkOrderQueryInfoVO.setMakeList(makeProcessVOS);
        return wxWorkOrderQueryInfoVO;
    }

    @Override
    public WxWorkOrderInfoVO findByOrderNum(String orderNum) {
        return obsOrderInfoMapper.findByOrderNum(orderNum);
    }

    @Override
    public OrderDetailVO detail(String orderNum) {
        //查询报障信息
        ObsOrderInfo info = getInfoByOrderNum(orderNum);
        //查询故障信息
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderNum);
        //协作信息(子工单)
        List<AssistMainVO> assistList = assistDetail(orderNum);
        //协作信息主工单
        assistMain(fault);
        //处理信息
        List<MakeProcessVO> makeProcessVOS = makeDetail(orderNum, fault);
        //评价信息
        OrderEvaluateVO orderEvaluateVO = evaluateDetail(orderNum);
        //获取当前处理人
        ObsOrderMake make = makeService
                .lambdaQuery()
                .eq(ObsOrderMake::getOrderNum, orderNum)
                .one();
        // 转换IP地址
        String ipAddress=sysDeptIpAddressService.joinIpAddress(info.getIpAddressId());
        return new OrderDetailVO(info,ipAddress, fault, make, assistList, makeProcessVOS, orderEvaluateVO);
    }

    private AssistMainDetailVO assistMain(ObsOrderFault fault) {
        //查询是否存在协作信息
        if (ObjectUtils.isEmpty(fault) || ObjectUtils.isEmpty(fault.getParentOrderNum())) {
            return null;
        }
        ObsOrderAssist one = assistService.lambdaQuery().like(ObsOrderAssist::getAssistOrderNum, fault.getOrderNum()).one();
        if (ObjectUtils.isEmpty(one)) {
            return null;
        }
        AssistMainDetailVO assistMainVO = new AssistMainDetailVO(one, fault);
        return assistMainVO;
    }

    @Override
    public void dealInvalid(Long data) {
        ObsOrderInfo orderInfo = getById(data);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new ServiceException("未找到通话记录");
        }
        lambdaUpdate().eq(ObsOrderInfo::getId, data).set(ObsOrderInfo::getDealType, OrderDealTypeConstant.INVALID).update();
    }

    @Override
    public void dealFind(FindUserDto dto) {
        ObsOrderInfo orderInfo = getById(dto.getId());
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new ServiceException("未找到通话记录");
        }
        lambdaUpdate().eq(ObsOrderInfo::getId, dto.getId())
                //设置处置方式
                .set(ObsOrderInfo::getDealType, OrderDealTypeConstant.END_LOOK)
                //设置寻找用户
                .set(ObsOrderInfo::getFindUser, dto.getUserId()).update();
    }

    @Override
    public void link(OrderLinkedDto dto) {
        ObsOrderInfo orderInfo = validLinked(dto);
        orderInfo.setLinkedCode(dto.getOrderNum());
        orderInfo.setDealType(OrderDealTypeConstant.LINK_ORDER);

//        ObsOrderFault orderFault = this.orderFaultService.getFaultByOrder(dto.getOrderNum());
//        OrderProcessRecordDto recordDto = OrderProcessRecordDto.builder()
//                .lastFaultState(orderFault.getCurrState())//当前状态
//                .orderNum(orderFault.getOrderNum())
//                .build();
//        processService.record(recordDto);
        //更新数据
        updateById(orderInfo);
    }

    @Override
    public OrderMakeInfoDto orderTime(String orderNum) {

        OrderMakeInfoDto makeInfoDto = new OrderMakeInfoDto();

        //获取工单异常
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderNum);
        //如果工单为空那么不返回处理人
        if (ObjectUtils.isEmpty(fault)) {
            return null;
        }
        //直接查询所有流程信息
        List<ObsOrderProcess> list = processService.lambdaQuery().eq(ObsOrderProcess::getOrderNum, orderNum).list();
        //查询第一次接单流程
        ObsOrderProcess receiving = list.stream().filter(data -> data.getOperState().equals(OrderProcessStateConstant.RECEIVING)).findFirst().orElse(null);
        Long responseTime=0L;
        if (!ObjectUtils.isEmpty(receiving)) {
            responseTime = (receiving.getCreateTime().getTime()-fault.getCreateTime().getTime()) / 1000;
            String responseTimeFormat = TimeFormatUtil.formatMinutes(responseTime);
            //设置响应时间
            makeInfoDto.setResponseTime(responseTime);
            makeInfoDto.setResponseTimeFormat(responseTimeFormat);
        }
        //获取处理耗时
        Long makeTime = orderFaultService.getMakeTimeSec(orderNum);
        if(ObjectUtils.isEmpty(makeTime)){
            makeTime = 0L;
        }
        //设置处理耗时
        makeInfoDto.setMakeTime(makeTime);
        String makeTimeFormat = TimeFormatUtil.formatMinutes(makeTime);
        makeInfoDto.setMakeTimeFormat(makeTimeFormat);
        //总耗时
        long totalTime=makeTime+responseTime;
        String totalTimeFormat = TimeFormatUtil.formatMinutes(totalTime);
        makeInfoDto.setTotalTime(totalTime);
        makeInfoDto.setTotalTimeFormat(totalTimeFormat);

        ObsOrderMake make = makeService.lambdaQuery().eq(ObsOrderMake::getOrderNum, orderNum).one();
        if(!ObjectUtils.isEmpty(make)){
            //设置处理人
            makeInfoDto.setMakeUser(make.getCreateUser());
            makeInfoDto.setMakeUserName(UserUtils.userIdToName(make.getCreateUser()));
        }

//        //处理耗时获取最后一次处理时间
//        ObsOrderProcess make = list.stream().filter(data ->
//                        //处理状态
//                        OrderProcessStateConstant.MAKING.equals(data.getOperState())
//                                //完成/处理状态
//                                && (OrderMakeTypeConstant.MAKING.equals(data.getMakeState()) || OrderMakeTypeConstant.COMPLETE.equals(data.getMakeState())))
//                //倒序排列
//                .sorted(Comparator.comparing(ObsOrderProcess::getCreateTime).reversed())
//                .findFirst().orElse(null);
//        if (!ObjectUtils.isEmpty(make)) {
//
//        }
        return makeInfoDto;
    }

    @Override
    public List<UserCacheVo> serverUser() {
        QueryWrapper<ObsOrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("distinct reception");
        List<UserCacheVo> list = list(queryWrapper).stream().map(data -> new UserCacheVo() {{
            setUserId(data.getReception());
        }}).collect(Collectors.toList());
        return ConversionUtil.conversionList(list, UserCacheVo.class);
    }

    @Override
    public List<HomeMineServerVO> mineServer(BaseTimeDto baseTimeDto) {
        return this.obsOrderInfoMapper.mineServer(baseTimeDto, SecurityUtils.getUserId());
    }

    @Override
    public List<HomeMineOrderVO> mineOrder(BaseTimeDto baseTimeDto) {
        //查询总数
        Integer total = this.obsOrderInfoMapper.mineOrderTotal(baseTimeDto, SecurityUtils.getUserId());
        //查询我的工单类型
        List<HomeMineOrderVO> list = this.obsOrderInfoMapper.mineOrder(baseTimeDto, SecurityUtils.getUserId());
        //设置总数
        list.add(new HomeMineOrderVO(total));
        return list;
    }

    @Override
    public HomeObsToDoVO todo() {
        //查询待处理报修数量
        Integer repair = this.obsOrderInfoMapper.todoRepair(SecurityUtils.getUserId());
        //查询待处理工单数量
        Integer order = this.obsOrderInfoMapper.todoOrder(SecurityUtils.getUserId());
        return new HomeObsToDoVO(repair, order);
    }

    @Override
    public HomeOrderSourceChartVO homeOrderSource(String type) {
        //开始时间
        Date beginDate = null;
        //结束时间
        Date endDate = DateUtils.toDateLastTime(DateUtils.getNowDate());
        //封装开始时间
        switch (type) {
            case "1":
                beginDate = DateUtils.addDays(DateUtils.getNowDate(), -6);
                break;
            case "2":
                beginDate = DateUtils.addDays(DateUtils.getNowDate(), -29);
                break;
            case "3":
                beginDate = DateUtils.addDays(DateUtils.getNowDate(), -365);
                break;
        }
        beginDate = DateUtils.getDateWithoutTime(beginDate);
        List<HomeOrderSourceVO> list = this.obsOrderInfoMapper.homeOrderSource(type, beginDate, endDate);
        List<HomeOrderSourceVO> newList = ConversionUtil.conversionList(list, HomeOrderSourceVO.class);
        if (CollectionUtil.isNotEmpty(newList)) {
            List<Object> dateSorts;
            if (type.equals("3")) {
                List<String> dateList = newList.stream().map(HomeOrderSourceVO::getDate).distinct().collect(Collectors.toList());
                dateSorts = dateList.stream().map(Integer::parseInt).sorted().collect(Collectors.toList());
            } else {
                List<String> dateList = newList.stream().map(HomeOrderSourceVO::getDate).distinct().collect(Collectors.toList());
                dateSorts = dateList.stream().sorted().collect(Collectors.toList());
            }
            List<String> legendData = new ArrayList<>();
            List<Map<String, Object>> series = new ArrayList<>();
            Map<String, List<HomeOrderSourceVO>> groupList = newList.stream().collect(Collectors.groupingBy(HomeOrderSourceVO::getSourceToName));
            groupList.forEach((key, valueList) -> {
                legendData.add(key);
                List<Object> yData = new ArrayList<>();
                dateSorts.forEach(a -> {
                    HomeOrderSourceVO sourceVO = valueList.stream().filter(b -> b.getDate().equals(String.valueOf(a))).findFirst().orElse(null);
                    if (sourceVO != null) {
                        yData.add(sourceVO.getCount());
                    } else {
                        yData.add(0);
                    }
                });
                Map<String, Object> yMap = new HashMap<>();
                yMap.put(key, yData);
                series.add(yMap);
            });
            HomeOrderSourceChartVO chartVO = HomeOrderSourceChartVO.builder()
                    .legendData(legendData)
                    .axisData(dateSorts)
                    .series(series)
                    .build();
            return chartVO;
        }
        return null;
    }

    @Override
    public HomeOrderSourceTotalVO homeOrderSourceTotal() {
        HomeOrderSourceTotalVO vo = new HomeOrderSourceTotalVO();
        //开始时间
        Date beginDate = DateUtils.getDateWithoutTime(DateUtils.getNowDate());
        //结束时间
        Date endDate = DateUtils.toDateLastTime(DateUtils.getNowDate());
        //封装开始时间
        beginDate = DateUtils.addDays(beginDate, -6);
        vo.setWeek(this.obsOrderInfoMapper.homeOrderSourceTotal(beginDate, endDate));
        beginDate = DateUtils.addDays(beginDate, -29);
        vo.setMonth(this.obsOrderInfoMapper.homeOrderSourceTotal(beginDate, endDate));
        beginDate = DateUtils.addDays(beginDate, -365);
        vo.setYear(this.obsOrderInfoMapper.homeOrderSourceTotal(beginDate, endDate));
        return vo;
    }

    @Override
    public List<HomeOrderFaultRankVO> orderFaultRank(BaseTimeDto baseTimeDto) {
        if (!ObjectUtils.isEmpty(baseTimeDto)) {
            baseTimeDto.setEndDate(DateUtils.toDateLastTime(baseTimeDto.getEndDate()));
        }
        //查询出所有故障计数
        List<HomeOrderFaultRankVO> list = this.obsOrderInfoMapper.orderFaultRank(baseTimeDto);
        //获取故障类型字典
        List<SysDictData> dictList = DictUtils.getDictCache(SysDictTypeConstant.OBS_FAULT_TYPE);
        Map<String, String> dictValue = DictUtils.mapDictValueToTopLevelDictValue(dictList);

        //合并数据
        List<HomeOrderFaultRankVO> collect = list
                .stream()
                //将子集设置为最上级
                .map(data -> {
                    data.setFaultType(dictValue.get(data.getFaultType()));
                    return data;
                })
                //过滤无法匹配故障类型的数据
                .filter(data -> !ObjectUtils.isEmpty(data.getFaultType()))
                //分组
                .collect(Collectors.groupingBy(HomeOrderFaultRankVO::getFaultType))
                .entrySet()
                .stream()
                .map(data -> {
                    HomeOrderFaultRankVO vo = new HomeOrderFaultRankVO();
                    vo.setFaultType(data.getKey());
                    vo.setCount(data.getValue().stream().mapToInt(HomeOrderFaultRankVO::getCount).sum());
                    return vo;
                })
                //排序
                .sorted(((o1, o2) -> o2.getCount() - o1.getCount()))
                .collect(Collectors.toList());
        return ConversionUtil.conversionList(collect, HomeOrderFaultRankVO.class);
    }

    @Override
    public List<HomeUserOrderRankVO> orderUserRank(BaseTimeDto baseTimeDto) {
        if (!ObjectUtils.isEmpty(baseTimeDto)) {
            baseTimeDto.setEndDate(DateUtils.toDateLastTime(baseTimeDto.getEndDate()));
        }
        List<UserOrderRankVO> rankVOS = this.obsOrderInfoMapper.orderUserRank(baseTimeDto);
        List<HomeUserOrderRankVO> collect = rankVOS.stream()
                //抽取用户
                .map(UserOrderRankVO::getUserId)
                //去重
                .distinct()
                //构造
                .map(data -> {
                    HomeUserOrderRankVO vo = new HomeUserOrderRankVO();
                    //初始化数据
                    vo.setProcess(0);
                    vo.setEnd(0);
                    vo.setUserId(data);
                    rankVOS.stream()
                            .filter(rank -> rank.getUserId().equals(data))
                            .forEach(rank -> {
                                if (rank.getType().equals("2")) {
                                    vo.setProcess(rank.getCount());
                                } else if (rank.getType().equals("3")) {
                                    vo.setEnd(rank.getCount());
                                }
                            });
                    return vo;
                })
                //排序
                .sorted(((o1, o2) -> (o2.getProcess() + o2.getEnd()) - (o1.getProcess() + o1.getEnd())))
                .collect(Collectors.toList());
        return ConversionUtil.conversionList(collect, HomeUserOrderRankVO.class);
    }

    @Override
    public List<HomeOrderWarningVO> orderWarning() {
        Date endDate = DateUtils.getNowDate();
        Date beginDate = null;
        String config = configService.selectConfigByKey(ConfigKeyConstant.ORDER_WARNING);
        //判断配置是否存在
        if (ObjectUtils.isEmpty(config)) {
            return null;
        }
        //计算开始时间
        beginDate = DateUtils.addMinutes(endDate, -JSONObject.parseObject(config).getInteger("time"));
        BaseTimeDto dto = new BaseTimeDto(beginDate, endDate);
        List<HomeOrderWarningVO> list = this.obsOrderInfoMapper.orderWarning(dto, JSONObject.parseObject(config).getInteger("count"));
        if (!CollectionUtils.isEmpty(list)) {
            //获取顶级类型
            Map<String, String> dictLevelValue = DictUtils.mapDictValueToTopLevelDictValue(DictUtils.getDictCache(SysDictTypeConstant.OBS_FAULT_TYPE));
            list.forEach(data -> {
                data.setParentFaultType(dictLevelValue.get(data.getFaultType()));
            });
            return ConversionUtil.conversionList(list, HomeOrderWarningVO.class);
        }
        return list;
    }

    @Override
    public Integer mineOrderNum() {
        return this.obsOrderInfoMapper.mineOrderNum(SecurityUtils.getUserId());
    }

    @Override
    public Integer mineAuditOrderNum() {
        return this
                .orderFaultService
                .lambdaQuery()
                .eq(ObsOrderFault::getCurrState, OrderCurrStateConstant.WAIT_AUDIT)
                .count();
    }

    @Override
    public WxOrderDailyVO daily(Date date) {
        BaseTimeDto dto = null;
        if (!ObjectUtils.isEmpty(date)) {
            dto = new BaseTimeDto(date);
        }
        List<HomeMineServerVO> vos = this.obsOrderInfoMapper.mineServer(dto, null);
        WxOrderDailyVO wxOrderDailyVO = new WxOrderDailyVO(vos);
        return ConversionUtil.conversion(wxOrderDailyVO, WxOrderDailyVO.class);
    }

    @Override
    public List<WxOrderDailyDetailVO> dailyDetail(Date date) {
        BaseTimeDto dto = null;
        if (!ObjectUtils.isEmpty(date)) {
            dto = new BaseTimeDto(date);
        }
        List<WxOrderDailyDetailVO> vos = this.obsOrderInfoMapper.dailyDetail(dto);
        return ConversionUtil.conversionList(vos, WxOrderDailyDetailVO.class);
    }

    @Override
    public void repeat(OrderLinkedDto dto) {
        ObsOrderInfo orderInfo = validLinked(dto);
        orderInfo.setLinkedCode(dto.getOrderNum());
        orderInfo.setDealType(OrderDealTypeConstant.LINKED_REPEAT);
        //更新数据
        updateById(orderInfo);
    }

    @Override
    public List<ServerPageVO> getWaitDispatch(ServerPageDto pageDto, BasePage page) {
        List<String> orderNumberList = obsOrderInfoMapper.getOrderNumberByTodoRepair(SecurityUtils.getUserId(),1);
        pageDto.setOrderNumList(orderNumberList);
        pageDto.setTemp(TempEnum.WAIT_DELIVERY);
        List<ServerPageVO> serverPageVOS = orderFaultService.serverPage(pageDto, page);
        return serverPageVOS;
    }

    @Override
    public List<ServerCallPageVO> getWaitCreate(ServerCallPageDto pageDto, BasePage page) {
        List<String> orderNumberList = obsOrderInfoMapper.getOrderNumberByTodoRepair(SecurityUtils.getUserId(),2);
        pageDto.setOrderNumList(orderNumberList);
        pageDto.setTemp(TempEnum.UNTENITED);
        List<ServerCallPageVO> serverCallPageVOS = orderFaultService.serverCallPage(pageDto, page);
        return serverCallPageVOS;
    }

    @Override
    public List<OrderAllPageVO> getWaitHandleList(OrderAllPageDto dto) {
        List<String> orderNumberList = obsOrderInfoMapper.getOrderNumberByTodoOrder(SecurityUtils.getUserId());
        dto.setOrderNumList(orderNumberList);
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize()).reasonable(true);
        List<OrderAllPageVO> orderAllPageVOS = orderFaultService.pageWholeOrder(dto);
        return orderAllPageVOS;
    }

    @Override
    public void phoneEnd(Long data) {
        ObsOrderInfo orderInfo = getById(data);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new ServiceException("未找到通话记录");
        }
        lambdaUpdate().eq(ObsOrderInfo::getId, data).set(ObsOrderInfo::getDealType, OrderDealTypeConstant.END_PHONE).update();
    }


    /**
     * 验证关联相关参数
     *
     * @author 伍绍宇
     * @date 2021/05/18
     */
    private ObsOrderInfo validLinked(OrderLinkedDto orderLinkedDto) {
        ObsOrderInfo mainInfo = getInfoByOrderNum(orderLinkedDto.getOrderNum());
        ObsOrderInfo info = this.getById(orderLinkedDto.getId());
        if (info == null || mainInfo == null) {
            throw new ServiceException("工单不存在");
        }
        if (info.getId().intValue() == mainInfo.getId().intValue()) {
            throw new ServiceException("不能关联自己");
        }
        return info;

    }

    private OrderEvaluateVO evaluateDetail(String orderNum) {
        ObsOrderEvaluate evaluate = evaluateService.lambdaQuery().eq(ObsOrderEvaluate::getOrderNum, orderNum).one();
        if (!ObjectUtils.isEmpty(evaluate)) {
            return ConversionUtil.conversion(new OrderEvaluateVO(evaluate), OrderEvaluateVO.class);
        }
        return null;
    }

    /**
     * 协作详情
     *
     * @param orderNum
     * @return
     */
    private List<AssistMainVO> assistDetail(String orderNum) {
        //查询该工单的协作信息
        List<ObsOrderAssist> assistList = assistService.lambdaQuery().eq(ObsOrderAssist::getOrderNum, orderNum).list();
        if (CollectionUtils.isEmpty(assistList)) {
            return null;
        }
        //获取子工单
        List<ObsOrderFault> childOrder = makeService.getChildOrder(orderNum);
        //查询子工单的协作人信息
        List<ObsOrderSend> sendList = orderSendService.lambdaQuery().in(ObsOrderSend::getOrderNum, childOrder.stream().map(ObsOrderFault::getOrderNum).collect(Collectors.toList())).list();
        return assistList.stream().map(data -> ConversionUtil.conversion(new AssistMainVO(data, childOrder, sendList), AssistMainVO.class)).collect(Collectors.toList());
    }

    /**
     * 处理信息
     */
    private List<MakeProcessVO> makeDetail(String orderNum, ObsOrderFault obsOrderFault) {
        List<ObsOrderProcess> makeProcesses = processService.lambdaQuery()
                .eq(ObsOrderProcess::getOrderNum, orderNum)
                .eq(ObsOrderProcess::getOperState, OrderProcessStateConstant.MAKING)
                .orderByDesc(ObsOrderProcess::getCreateTime)
                .list();
        List<MakeProcessVO> collect = makeProcesses.stream().map(data -> new MakeProcessVO(data,obsOrderFault)).collect(Collectors.toList());
        return ConversionUtil.conversionList(collect, MakeProcessVO.class);
    }
}
